<?php
// +----------------------------------------------------------------------
// | Description: 公共模型,所有模型都可继承此模型，基于RESTFUL CRUD操作
// +----------------------------------------------------------------------
// | Author: 董鹏
// +----------------------------------------------------------------------

namespace app\common\model;

use think\Model;

class Common extends Model
{
    protected $param;
    protected $map = [];
    protected $orderByString; // 排序规则
    protected $specialConditions; // 特殊条件
    protected $fuzzyConditions = null;
    protected $clearConditions = null; // 精确查询字段
    protected $returnFields = '';
    protected $rangeConditions = null;
    protected $union_fuzzyConditions = null;
    protected $foreignConditions = null;

    /**
     * 解析搜索条件
     */
    public function getDataList()
    {
        $this->page = $this->param['page'] or 1;
        $this->limit = $this->param['limit'] or $this->limit;
        $this->orderByString = $this->param['orderByString'];

        $this->specialCondition();
        $this->M_fuzzy();
        $this->M_clear();
        $this->M_range();
        $this->M_union_field();
        $this->M_UnionSelect();
        $this->M_order();

        if ($this->limit == -1) {
            $resData = $this->field($this->returnFields)->select();
        } else {
            $resData = $this->field($this->returnFields)->page($this->page, $this->limit)->select();
        }
// p($this -> getlastsql());
        $this->specialCondition();
        $this->M_fuzzy();
        $this->M_clear();
        $this->M_range();
        $this->M_union_field();
        $this->M_UnionSelect();
        $this->M_order();

        $dataCount = $this->count();
        $data['list'] = $resData;
        $data['dataCount'] = $dataCount;
        return $this->filter($data);
    }
    /**
     * 过滤
     *
     * @return void
     */
    public function filter($data)
    {
        return $data;
    }

    /**
     * 模糊查询
     */
    public function M_fuzzy()
    {
        if (!$this->fuzzyConditions) {
            return;
        }
        $fuzzys = $this->fuzzyConditions;
        foreach ($fuzzys as $k => $v) {
            if ($this->param[$v]) {
                $this->where('' . $this->name . '.' . $v, 'like', '%' . $this->param[$v] . '%');
            }

        }
    }

    /**
     * 精确查询
     */
    public function M_clear()
    {
        if (!$this->clearConditions) {
            return;
        }
        $clears = $this->clearConditions;
        foreach ($clears as $k => $v) {
            if ($this->param[$v] != null) {
                $this->where('' . $this->name . '.' . $v, '=', $this->param[$v]);
            }

        }
    }

    /**
     * 范围查询
     */
    public function M_range()
    {
        if (!$this->rangeConditions) {
            return;
        }
        $ranges = $this->rangeConditions;
        foreach ($ranges as $k => $v) {
            if ($this->param[$v]) {
                $temp_arr = explode('--', $this->param[$v]);
                $temp_min = strtotime($temp_arr[0]);
                $temp_max = strtotime($temp_arr[1]);
                unset($temp_arr);
                $this->where('' . $this->name . '.' . $v, '>=', $temp_min)->where('' . $this->name . '.' . $v, '<=', $temp_max);
            }
        }
    }

    /**
     * 多表多条件排序
     */
    public function M_order()
    {
        if (!$this->orderByString) {
            return;
        }
        $orderBy = $this->orderByString;
        $orderArr = explode('.', $orderBy);
        if (!isset($this->union_fuzzyConditions)) {
            if ($orderArr[1] == 'descending') {
                $this->order('' . $this->name . '.' . $orderArr[0] . ' DESC');
            } else {
                $this->order('' . $this->name . '.' . $orderArr[0]);
            }
        } else {
            $union = $this->union_fuzzyConditions;
            foreach ($union as $k => $v) {
                if ($v[1] == $orderArr[0]) {
                    if ($orderArr[1] == 'descending') {
                        $this->order($v[0] . '.' . $orderArr[0] . ' DESC');
                    } else {
                        $this->order($v[0] . '.' . $orderArr[0]);
                    }
                } else {
                    if ($orderArr[1] == 'descending') {
                        $this->order('' . $this->name . '.' . $orderArr[0] . ' DESC');
                    } else {
                        $this->order('' . $this->name . '.' . $orderArr[0]);
                    }
                }
            }
        }
    }

    /**
     * 自定义全局特殊搜索条件
     */
    public function specialCondition()
    {
        $name = $this->specialConditions[0];
        $condition = $this->specialConditions[1];
        $value = $this->specialConditions[2];
        $this->where($name, $condition, $value);
    }

    /**
     * 联合查询
     */
    public function M_UnionSelect()
    {
        if (!$this->foreignConditions) {
            return;
        }
        $foreignConditions = $this->foreignConditions;
        foreach ($foreignConditions as $k => $v) {
            if ($v[2]) {
                $this->join($k, $k . '.' . $v[0] . '=' . $v[2] . '.' . $v[1]);
            } else {
                $arr = explode('.', $v[1]);
                if (count($arr) == 2) {
                    $this->join($k, $k . '.' . $v[0] . '=' . $v[1]);
                } else if (count($arr) == 1) {
                    $this->join($k, $k . '.' . $v[0] . '=' . '' . $this->name . '.' . $v[1]);
                }
            }
        }
    }

    /**
     * 对字段的联合查询
     */
    public function M_union_field()
    {
        $this->M_union_fuzzy();
    }

    /**
     * 字段的联合模糊查询
     */
    public function M_union_fuzzy()
    {
        if (!$this->union_fuzzyConditions) {
            return;
        }
        $union_fuzzys = $this->union_fuzzyConditions;
        foreach ($union_fuzzys as $k => $v) {
            if ($this->param[$v[1]]) {
                $this->where($v[0] . '.' . $v[1], 'like', '%' . $this->param[$v[1]] . '%');
            }

        }
    }

    /**
     * 自定义特殊字段
     */
    public function SetspecialCondition($name, $condition, $value)
    {
        $this->specialConditions = [$name, $condition, $value];
    }

    /**
     * 设置请求参数
     */
    public function setParam($param)
    {
        $this->param = $param;
    }

    /**
     * [getDataById 根据主键获取详情]
     * @linchuangbin
     * @DateTime  2017-02-10T21:16:34+0800
     * @param     string                   $id [主键]
     * @return    [array]
     */
    public function getDataById($id = '')
    {
        $data = $this->get($id);
        if (!$data) {
            $this->error = '暂无此数据';
            return false;
        }
        return $data;
    }

    /**
     * [createData 新建]
     * @linchuangbin
     * @DateTime  2017-02-10T21:19:06+0800
     * @param     array                    $param [description]
     * @return    [array]                         [description]
     */
    public function createData($param)
    {
        // 验证
        $validate = validate($this->name);
        if (!$validate->check($param)) {
            $this->error = $validate->getError();
            return false;
        }
        try {
            $this->data($param)->allowField(true)->save();
            return true;
        } catch (\Exception $e) {
            $this->error = '添加失败';
            return false;
        }
    }

    /**
     * 通过id修改用户
     * @param  array   $param  [description]
     */
    public function updateDataById($param, $id)
    {
        try {
            $this->allowField(true)->save($param, [$this->getpk() => $id]);
            return true;
        } catch (\Exception $e) {
            $this->error = '编辑失败';
            return false;
        }
    }

    /**
     * [delDataById 根据id删除数据]
     * @linchuangbin
     * @DateTime  2017-02-11T20:57:55+0800
     * @param     string                   $id     [主键]
     * @param     boolean                  $delSon [是否删除子孙数据]
     * @return    [type]                           [description]
     */
    public function delDataById($id = '', $delSon = false)
    {
        $this->startTrans();
        try {
            $this->where($this->getPk(), $id)->delete();
            if ($delSon && is_numeric($id)) {
                // 删除子孙
                $childIds = $this->getAllChild($id);
                if ($childIds) {
                    $this->where($this->getPk(), 'in', $childIds)->delete();
                }
            }
            $this->commit();
            return true;
        } catch (\Exception $e) {
            $this->error = '删除失败';
            $this->rollback();
            return false;
        }
    }

    /**
     * [delDatas 批量删除数据]
     * @linchuangbin
     * @DateTime  2017-02-11T20:59:34+0800
     * @param     array                   $ids    [主键数组]
     * @param     boolean                 $delSon [是否删除子孙数据]
     * @return    [type]                          [description]
     */
    public function delDatas($ids = [], $delSon = false)
    {
        if (empty($ids)) {
            $this->error = '删除失败';
            return false;
        }

        // 查找所有子元素
        if ($delSon) {
            foreach ($ids as $k => $v) {
                if (!is_numeric($v)) {
                    continue;
                }

                $childIds = $this->getAllChild($v);
                $ids = array_merge($ids, $childIds);
            }
            $ids = array_unique($ids);
        }

        try {
            $this->where($this->getPk(), 'in', $ids)->delete();
            return true;
        } catch (\Exception $e) {
            $this->error = '操作失败';
            return false;
        }
    }

    /**
     * [enableDatas 批量启用、禁用]
     * @AuthorHTL
     * @DateTime  2017-02-11T21:01:58+0800
     * @param     string                   $ids    [主键数组]
     * @param     integer                  $status [状态1启用0禁用]
     * @param     [boolean]                $delSon [是否删除子孙数组]
     * @return    [type]                           [description]
     */
    public function enableDatas($ids = [], $status = 1, $delSon = false)
    {
        if (empty($ids)) {
            $this->error = '操作失败';
            return false;
        }

        // 查找所有子元素
        if ($delSon && $status === '0') {
            foreach ($ids as $k => $v) {
                $childIds = $this->getAllChild($v);
                $ids = array_merge($ids, $childIds);
            }
            $ids = array_unique($ids);
        }
        try {
            $this->where($this->getPk(), 'in', $ids)->setField('status', $status);
            return true;
        } catch (\Exception $e) {
            $this->error = '操作失败';
            return false;
        }
    }

    /**
     * 获取所有子孙
     */
    public function getAllChild($id, &$data = [])
    {
        $map['pid'] = $id;
        $childIds = $this->where($map)->column($this->getPk());
        if (!empty($childIds)) {
            foreach ($childIds as $v) {
                $data[] = $v;
                $this->getAllChild($v, $data);
            }
        }
        return $data;
    }

}
